/*
 * @(#)XfdmClusteringDialog.java        1.0 2009/01/01
 *
 * This file is part of Xfuzzy 3, a design environment for fuzzy logic
 * based systems.
 *
 * (c) 2000 IMSE-CNM. The authors may be contacted by the email address:
 *                    xfuzzy-team@imse.cnm.es
 *
 * Xfuzzy is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Xfuzzy is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

package xfuzzy.xfdm.view;

import xfuzzy.util.*;
import xfuzzy.xfdm.model.XfdmAlgorithm;
import xfuzzy.xfdm.model.algorithm.XfdmFixedClustering;
import xfuzzy.xfdm.view.listener.*;
import javax.swing.*;
import java.awt.*;

/**
 * Ventana de configuraci�n del algoritmo de clustering fijo
 * 
 * @author Francisco Jos� Moreno Velo
 *
 */
public class XfdmClusteringDialog extends JDialog implements IXfdmAlgorithmDialog, IXfdmFrame {

	/**
	 * C�digo asociado a la clase serializable
	 */
	private static final long serialVersionUID = 95505666603012L;

	//----------------------------------------------------------------------------//
	//                            MIEMBROS PRIVADOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Algoritmo a configurar
	 */
	private XfdmFixedClustering algorithm;
	
	/**
	 * Campos para introducir los valores de configuraci�n
	 */
	private XTextField[] text;
	
	/**
	 * Elecci�n del algoritmo de clustering
	 */
	private JComboBox combo;
	
	/**
	 * Bot�n de la opci�n de aprendizaje
	 */
	private JRadioButton learning;
	
	/**
	 * Marcador de configuraci�n realizada 
	 */
	private boolean conf;

	//----------------------------------------------------------------------------//
	//                               CONSTRUCTOR                                  //
	//----------------------------------------------------------------------------//

	/**
	 * Constructor
	 */
	public XfdmClusteringDialog(Xfdm xfdm, XfdmAlgorithm alg){
		super(xfdm,"Xfdm",true);
		if(alg != null && alg instanceof XfdmFixedClustering) {
			this.algorithm = (XfdmFixedClustering) ((XfdmFixedClustering) alg).clone();
		} else {
			this.algorithm = new XfdmFixedClustering();
		}
		build();
		set();
	}

	//----------------------------------------------------------------------------//
	//                             M�TODOS P�BLICOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Muestra el di�logo
	 */
	public static XfdmFixedClustering showDialog(Xfdm xfdm,XfdmAlgorithm algorithm) {
		XfdmClusteringDialog dialog = new XfdmClusteringDialog(xfdm, algorithm);
		dialog.setVisible(true);
		return dialog.getAlgorithm();
	}

	/**
	 * Obtiene el algoritmo
	 */
	public XfdmFixedClustering getAlgorithm() {
		if(this.conf) return this.algorithm;
		return null;
	}

	/**
	 * Acci�n de almacenar los datos y cerrar la ventana
	 */
	public void actionSet() {
		try { get(); } catch(Exception ex) { return; }
		this.conf = true;
		setVisible(false); 
	}

	/**
	 * Acci�n de cerrar la ventana
	 */
	public void actionCancel() {
		this.conf = false;
		setVisible(false); 
	}

	/**
	 * Acci�n de cerrar la ventana
	 */
	public void close() {
		this.conf = false;
		setVisible(false); 
	}

	//----------------------------------------------------------------------------//
	//                             M�TODOS PRIVADOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Generaci�n de la ventana
	 */
	private void build() {
		String lb[] = {"Set", "Cancel"};
		XCommandForm form = new XCommandForm(lb,lb,new XfdmAlgorithmActionListener(this));
		form.setCommandWidth(150);
		form.block();

		combo = new JComboBox();
		combo.setBackground(XConstants.textbackground);
		combo.setEditable(false);
		combo.setFont(XConstants.textfont);
		combo.addItem("Hard C-Means");
		combo.addItem("Fuzzy C-Means");
		combo.addItem("Gustafson-Kessel");
		combo.addItem("Gath-Geva");

		text = new XTextField[4];
		text[0] = new XTextField("");
		text[1] = new XTextField("");
		text[2] = new XTextField("");
		text[3] = new XTextField("");

		learning = new JRadioButton("Activate");
		Box lrnbox = new Box(BoxLayout.X_AXIS);
		lrnbox.add(Box.createHorizontalStrut(20));
		lrnbox.add(learning);
		lrnbox.add(Box.createHorizontalGlue());

		JPanel panel = new JPanel();
		panel.setLayout(new GridLayout(6,2));
		panel.add(new XLabel("Clustering algorithm"));
		panel.add(combo);
		panel.add(new XLabel("Number of clusters"));
		panel.add(text[0]);
		panel.add(new XLabel("Limit on iterations"));
		panel.add(text[1]);
		panel.add(new XLabel("Fuzziness index"));
		panel.add(text[2]);
		panel.add(new XLabel("Limit on cluster variation"));
		panel.add(text[3]);
		panel.add(new XLabel("Learning option"));
		panel.add(lrnbox);

		Container content = getContentPane();
		content.setLayout(new BoxLayout(content,BoxLayout.Y_AXIS));
		content.add(new XLabel("Parameter selection for Fixed Clustering"));
		content.add(Box.createVerticalStrut(5));
		content.add(panel);
		content.add(Box.createVerticalStrut(5));
		content.add(form);

		setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		addWindowListener(new XfdmWindowListener(this));
		pack();
		setLocation();
	}

	/**
	 * Coloca la ventana en la pantalla	
	 */
	private void setLocation() {
		Dimension frame = getSize();
		Dimension screen = getToolkit().getScreenSize();
		setLocation((screen.width - frame.width)/2,(screen.height - frame.height)/2);
	}

	/**
	 * Actualiza los par�metros de configuraci�n del algoritmo
	 */
	private void set() {
		combo.setSelectedIndex(algorithm.getClustering());
		text[0].setText(""+algorithm.getNumberOfClusters());
		text[1].setText(""+algorithm.getNumberOfIterations());
		text[2].setText(""+algorithm.getFuzziness());
		text[3].setText(""+algorithm.getEpsilon());
		learning.setSelected(algorithm.getLearning());
	}

	/**
	 * Detecta posibles errores en los valores de los par�metros
	 */
	private boolean get() {
		boolean error = false;
		int num_cluster = -1;
		if(text[0].getText().trim().length() > 0) {
			try { num_cluster = Integer.parseInt(text[0].getText().trim()); }
			catch(Exception ex) { error = true; text[0].setText(""); }
		}
		if(num_cluster <= 0) error = true;

		int iteration = -1;
		if(text[1].getText().trim().length() > 0) {
			try { iteration = Integer.parseInt(text[1].getText().trim()); }
			catch(Exception ex) { error = true; text[1].setText(""); }
		}
		if(iteration <= 0) error = true;

		double fuzziness = -1;
		if(text[2].getText().trim().length() > 0) {
			try { fuzziness = Double.parseDouble(text[2].getText().trim()); }
			catch(Exception ex) { error = true; text[2].setText(""); }
		}
		if(fuzziness <= 1.0) error = true;

		double epsilon = -1;
		if(text[3].getText().trim().length() > 0) {
			try { epsilon = Double.parseDouble(text[3].getText().trim()); }
			catch(Exception ex) { error = true; text[3].setText(""); }
		}
		if(epsilon <= 0 || epsilon >= 1.0) error = true;

		if(error) {
			XDialog.showMessage(text[0],"Not a valid value");
			return false;
		}

		algorithm.setClustering(combo.getSelectedIndex());
		algorithm.setNumberOfClusters(num_cluster);
		algorithm.setNumberOfIterations(iteration);
		algorithm.setFuzziness(fuzziness);
		algorithm.setEpsilon(epsilon);
		algorithm.setLearning(learning.isSelected());
		return true;
	}

}


